﻿//AcademicPlanner - course registration planning web app.
//Copyright (C) 2009  Boubacar Diallo

//This program is free software; you can redistribute it and/or
//modify it under the terms of the GNU General Public License
//as published by the Free Software Foundation; either version 2
//of the License, or (at your option) any later version.

//This program is distributed in the hope that it will be useful,
//but WITHOUT ANY WARRANTY; without even the implied warranty of
//MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//GNU General Public License for more details.

//You should have received a copy of the GNU General Public License
//along with this program; if not, write to the Free Software
//Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using AcademicPlanner.Data.Entities;
using NHibernate.Tool.hbm2ddl;
using NHibernate;

namespace AcademicPlanner.Data.Repositories
{
	/// <summary>
	/// AccountEntityRepository serves as the repository for <c>AccountEntity</c>s.
	/// </summary>
	/// <since>1.0</since>
	public class AccountEntityRepository : EntityRepository<AccountEntity>
	{
		internal override string DBTableName { get { return "accounts"; } }


		private AccountEntityRepository()
		{
			namedQueriesPrefix = "AccountEntity";
		}

		private class InstanceHolder
		{
			internal static AccountEntityRepository INSTANCE = new AccountEntityRepository();
		}


		/// <summary>
		/// The the single instance of AccountEntityRepository.
		/// </summary>
		/// <returns>The single instance of AccountEntityRepository.</returns>
		/// <since>1.0</since>
		public static AccountEntityRepository GetInstance()
		{
			return InstanceHolder.INSTANCE;
		}


		/// <summary>
		/// Finds the <c>AccountEntity</c> whose <c>UserEntity</c> has the given username from
		/// the persistence layer.
		/// </summary>
		/// <param name="pUserEntityName">The username.</param>
		/// <returns>The <c>AccountEntity</c> or <c>null</c>.</returns>
		/// <exception cref="T:AcademicPlanner.Data.DataException">
		/// Thrown with an error code of <c>DataErrorCode.QUERY_ACCOUNT_ENTITY_BY_USER_ENTITY_NAME_FAILED</c>
		/// when an error is reported by NHibernate. The <c>HibernateException</c> is
		/// accessible via the <c>InnerException</c> property.
		/// </exception>
		/// <since>1.0</since>
		public AccountEntity FindByUserEntityName(string pUserEntityName)
		{
			var vQuery = GetNamedQuery("by.userentity.name");
			return QueryByUserEntityName(vQuery, pUserEntityName);
		}

		private AccountEntity QueryByUserEntityName(IQuery pQuery, string pUserEntityName)
		{
			AccountEntity rEnt = null;

			try
			{
				pQuery.SetString("userentityName", pUserEntityName);
				rEnt = pQuery.UniqueResult<AccountEntity>();
			}
			catch (HibernateException vHx)
			{
				var vDx = new DataException(DataErrorCode.QUERY_ACCOUNT_ENTITY_BY_USER_ENTITY_NAME_FAILED, vHx);
				throw vDx;
			}

			return rEnt;
		}

		/// <summary>
		/// Filters the given <c>AccountEntity</c>s and returns the
		/// <c>AccountEntity</c> whose <c>UserEntity</c> has the given username.
		/// </summary>
		/// <remarks>
		/// A <see cref="T:AcademicPlanner.Data.DataException"/> may be inderectly
		/// thrown with error code <c>DataErrorCode.QUERY_ACCOUNT_ENTITY_BY_USER_ENTITY_NAME_FAILED</c>
		/// when an error is reported by NHibernate. The <c>HibernateException</c> is
		/// accessible via the <c>InnerException</c> property.
		/// </remarks>
		/// <param name="pFilterList">The <c>AccountEntity</c>s to filter.</param>
		/// <param name="pUserEntityName">The username.</param>
		/// <returns>The <c>AccountEntity</c> or <c>null</c>.</returns>
		/// <since>1.0</since>
		public AccountEntity FilterByUserEntityName(ICollection pFilterList, string pUserEntityName)
		{
			AccountEntity rEnt;
			var vFilterQuery = "where UserEntity.Name = :userentityName";
			var vFilter = GetFilterQuery(pFilterList, vFilterQuery);

			DSAS.DisableFilters();
			rEnt = QueryByUserEntityName(vFilter, pUserEntityName);
			DSAS.EnableFilters();

			return rEnt;
		}
	}
}
